#include <jni.h>
#include <android/log.h>

#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#include <binder/IMemory.h>
#include <gui/SurfaceComposerClient.h>

#include <SkImageEncoder.h>
#include <SkBitmap.h>
#include <SkData.h>
#include <SkStream.h>

#include <utils/Log.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>

#include <binder/IMemory.h>
#include <gui/ISurfaceComposer.h>

#include <SkImageEncoder.h>
#include <SkImageDecoder.h>
#include <SkBitmap.h>

#include <android/native_window.h>
#include <android/native_window_jni.h>

//#include <surfaceflinger/Surface.h>
//#include <surfaceflinger/ISurface.h>
//#include <surfaceflinger/SurfaceComposerClient.h>
#include <gui/Surface.h>

#include "capjni.h"
#include "caevent.h"
#include "catimer.h"
#include "cathread.h"
#include "calist.h"
#include "cabuffer.h"
#include "casock.h"

#include "turbojpeg.h"

#include "imgtcpsr.h"

#define mlog(...) __android_log_print(ANDROID_LOG_INFO, THIS_TAG, __VA_ARGS__)

#define THIS_TAG "capjni"



using namespace android;


#pragma pack(1)
// mirror obj
typedef struct {
	unsigned char magic;
	unsigned short seq;
	unsigned long size;
}  packet_hdr;
#pragma pack()


jobject gMirrorSurface=NULL;
static int gMode;


static int gImgw, gImgh;

JavaVM *gJavaVM;

jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
  JNIEnv *env;
  gJavaVM = vm;

  mlog("JNI_OnLoad called");
  if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
    mlog("Failed to get the environment using GetEnv()");
    return -1;
  }
  return JNI_VERSION_1_4;
}



JNIEXPORT jint JNICALL Java_com_kt_hwan_MScreenCap_nvstart(JNIEnv *env, jobject obj)
{


	return 0;
}

/*
 * Class:     com_kt_hwan_MScreenCap
 * Method:    nvstop
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_kt_hwan_MScreenCap_nvstop(JNIEnv *env, jobject obj)
{

}


JNIEXPORT void JNICALL Java_com_kt_hwan_MScreenCap_nvdraw(JNIEnv *env, jobject jobj, jobject sf)
{
}




JNIEXPORT jint JNICALL Java_com_kt_hwan_MScreenCap_nvOpenMirror(JNIEnv *env, jobject jobj, jobject jsurface, jint mode)
{
	mlog("== open mirror, mode=%d\n", mode);
	if(jsurface != NULL)
		gMirrorSurface = env->NewGlobalRef(jsurface);
	gMode = mode;


	
	
	return 0;
}


JNIEXPORT jint JNICALL Java_com_kt_hwan_MScreenCap_nvStartRecvFrame(JNIEnv *env, jobject jobj, jstring jipaddr, jint port, jint trans)
{
	RecvStart(env, jipaddr, port, gImgw, gImgh, trans);
	return 0;
}

JNIEXPORT jint JNICALL Java_com_kt_hwan_MScreenCap_nvStopRecvFrame(JNIEnv *env, jobject jobj)
{
	mlog("== stop recv thread....\n");
	RecvStop();	
	env->DeleteGlobalRef(gMirrorSurface);
	gMirrorSurface = NULL;
	return 0;
}

JNIEXPORT jint JNICALL Java_com_kt_hwan_MScreenCap_nvStartSendFrame(JNIEnv *env, jobject jobj, jstring jipaddr, jint jport, jint trans)
{
	mlog("== start send frame....\n");
	SendStart(env, jipaddr, jport, gImgw, gImgh, trans);
	return 0;
}

JNIEXPORT void JNICALL Java_com_kt_hwan_MScreenCap_nvStopSendFrame(JNIEnv *env, jobject jobj)
{
	mlog("== stop send frame....\n");
	SendStop();
}


JNIEXPORT void JNICALL Java_com_kt_hwan_MScreenCap_nvCaptureTx(JNIEnv *env, jobject jobj)
{
	//es_postmsg(TCX, UM_CAPTURE, 0, 0);
	ScreenshotClient cl;
	cl.update();
}

JNIEXPORT void JNICALL Java_com_kt_hwan_MScreenCap_nvSetMirrorCfg(JNIEnv *env, jobject jobj, jint w, jint h)
{
	mlog("== set mirror cfg, w=%d, h=%d\n", w, h);
	gImgw = w;
	gImgh = h;
}



